/**
  ******************************************************************************
  * @file    flash.c
  * @author  测试1组（houtiezhu）
  * @version v0
  * @date    09-07-2019
  *
  * @verbatim
  **/
/* Includes ------------------------------------------------------------------*/

#include "define.h"
#include "disp.h"
#include "power.h"
#include "clk.h"
#include "gpio.h"
#include "time.h"
#include "uart.h"
#include "spk.h"
#include "flash.h"
#include "adc.h"
#include "algo.h"
#include "bp.h"
#include "func.h"
#include "op.h"
#include "pwm.h"
#include "SD93F115B_flash.h"




#define wb(addr, value)     (*((u8  volatile *) (addr)) = value)
#define rb(addr)            (*((u8  volatile *) (addr)))
#define whw(addr, value)    (*((u16 volatile *) (addr)) = value)
#define rhw(addr)           (*((u16 volatile *) (addr)))
#define ww(addr, value)     (*((u32 volatile *) (addr)) = value)
#define rw(addr)            (*((u32 volatile *) (addr)))

#define LIBCFG_FLASH_PAGESIZE             (512)
#define FLASH_PAGE_SIZE               (LIBCFG_FLASH_PAGESIZE)

uint8 	BPLevelType;
uint8   Det_DIA;
uint8   ResultDataS; 		 	//SYS
uint8   ResultDataD; 		 	//DIA
uint8   ResultDataH; 		 	//PUL
uint8   ResultDataDA;		 	//day
uint8   ResultDataHO;		 	//hour
uint8   ResultDataMI;		 	//min

u32 RevData[512/4];//test


volatile union byte_bit	IDbuffer;




void User_flash_Init(void)
{
	//RCC_AHBClockCmd(FLITFEN,ENABLE);
}


//=========================================================================================

//u8			MemoryMode;
//u8			MemoryFull;
//u16			EEPROMin;
//u8			UserA;
//u8			ReadEepromError;
//u8   			ShiftBit;

u8   	MemoryIndex;
u8   	inbyte[8];
u8   	outbyte[8];
u32		Readbuf[4];
u32		Writebuf[4];
u8		MemorySet;
u8 		MemoryEndIndex;

//================================USER FLASH===============================================
//100K之后作为非code存储,all 20K
//0x08000000~ 0x0801DFFF
//#define UserStartAddress    (0x08000000 + 1024 * 100) //A用户数据存储
#define UserEndAddress      (0x08000000 + 1024 * (100+2))//2K*2 A/B
//#define UserBStartAddress UserEndAddress  //B用户数据存储

#define BackStartAddress    (UserStartAddress+4 * 1024)//AB用户数据存储备份4K
#define BackEndAddress      (UserStartAddress+8 * 1024)

/*
//@flash.h
#define	 FunctionAdd		(UserStartAddress + 10 * 1024)
#define	 FunctionBak		(UserStartAddress + 11 * 1024)

#define 	CalBak				(UserStartAddress + 12 * 1024)
#define 	CalAdd				(UserStartAddress + 13 * 1024)

#define valveoffsetAdd			(14 * 1024)
#define	EEPROMCheckAdd			(15 * 1024)//待定
#define	UserSetAdd				(16 * 1024)//待定
#define	WorkModeAdd				(17 * 1024)//待定

#define	UserBOffSet			256	  //2048/8=256
*/




u32 MemBack[4096/4];
//u32 BMemBack[2048/4];
//RD 4byte
uint8 FLASH_Read(u32 AddrStart,u32* pData,u32 Length)
{
  u32 Addr;

	if((AddrStart > 0x08000000 + 120*1024)||(AddrStart < 0x08000000 + 100*1024))return FALSE; //128*1024
	AddrStart /= 4;
	AddrStart *= 4;
	Length /= 4;
	Length *= 4;
	//FLASH_Unlock();
  for (Addr = AddrStart; Addr < AddrStart + Length; Addr += 4)
  {

		*pData  = rw(Addr);
		pData++;

  }
	//FLASH_Lock();
	return TRUE;
}



//1byte,Addr
uint8 FLASH_ReadAddr(u32 AddrStart)
{
	u8 AddrData;
	if((AddrStart > 0x08000000 + 120*1024)||(AddrStart < 0x08000000 + 100*1024))return 0;//1~4 as mem
	//FLASH_Unlock();
	AddrData = rb(AddrStart);
	//FLASH_Lock();
	return AddrData; //读一个字节

}


//1byte,AddrOffSet
uint8 FLASH_ReadAddrOffset(u32 AddrStarOffSet)
{
	u32 Addr;
	u8 AddrData;

	if((AddrStarOffSet > 20*1024)||(AddrStarOffSet < 4*1024))return 0;//1~4 as mem
	//FLASH_Unlock();
	Addr = UserStartAddress + AddrStarOffSet;
	AddrData = rb(Addr);
	//FLASH_Lock();
	return AddrData; //读一个字节

}





//WR 4byte
uint8 FLASH_WrDataProgram(u32 AddrStart,u32* pData,u32 Length)
{
	u32 Addr;
	FLASH_Status FLASHState;

	if((AddrStart > 0x08000000 + 120*1024)||(AddrStart < 0x08000000 + 100*1024))return FALSE;
	AddrStart /= 4;
	AddrStart *= 4;
	Length /= 4;
	Length *= 4;
	//FLASH_Unlock();
  for (Addr = AddrStart; Addr < AddrStart + Length; Addr += 4)
  {
	FLASHState = FLASH_ProgramWord(Addr,*pData);
    if (FLASHState != FLASH_COMPLETE)
    {
      //err++;
		//FLASH_Lock();
		return FALSE;
    }
	else pData++;
  }
	//FLASH_Lock();
	return TRUE;
}

//WR 1byte ,ADDR
uint8 FLASH_WrByteDataProgram(u32 AddrStart,u8 pData)
{
	u32 Addr;
	FLASH_Status FLASHState;

	if((AddrStart > 0x08000000 + 120*1024)||(AddrStart < 0x08000000 + 100*1024))return FALSE;
	//AddrStart /= 4;
	//AddrStart *= 4;
	Addr = AddrStart;
	//FLASH_Unlock();

	FLASHState = FLASH_ProgramByte(Addr,pData);
	if (FLASHState != FLASH_COMPLETE)
    {
      //err++;
		//FLASH_Lock();
		return FALSE;
    }
	else
	{
		//FLASH_Lock();
		return TRUE;
	}

}

//WR 1byte ,addroffset
uint8 FLASH_WrByteData(u32 AddrStarOffSet,u8 pData)
{
	u32 Addr;
	FLASH_Status FLASHState;

	if((AddrStarOffSet > 20*1024)||(AddrStarOffSet < 4*1024))return FALSE;//1~4 as mem
	Addr = UserStartAddress + AddrStarOffSet;

	//FLASH_Unlock();

	FLASHState = FLASH_ProgramByte(Addr,pData);
	if (FLASHState != FLASH_COMPLETE)
    {
      //err++;
		//FLASH_Lock();
		return FALSE;
    }
	else
	{
		//FLASH_Lock();
		return TRUE;
	}

}


//512
uint8 FLASH_PageErase(u32 AddrStart,u16 PageLength )
{
	u32 Addr;
	FLASH_Status  FLASHState;

	if((AddrStart > 0x08000000 + 120*1024)||(AddrStart < 0x08000000 + 100*1024))return FALSE;
	AddrStart /= 512;
	AddrStart *= 512;
	//FLASH_Unlock();
  for (Addr = AddrStart; Addr < AddrStart + PageLength * FLASH_PAGE_SIZE;Addr += FLASH_PAGE_SIZE)// 页擦除
  {
    FLASHState = FLASH_ErasePage(Addr);//FLASH_ErasePage(uint32_t Page_Address)
    if (FLASHState != FLASH_COMPLETE)
    {
      //err++;
		//FLASH_Lock();
		return FALSE;
    }
  }
	//FLASH_Lock();
	return TRUE;
}




uint8 Byte_RDNO(uint32 MEM_ADDR)
{
	//return FLASH_ReadAddrOffset(MEM_ADDR);
	return FLASH_ReadAddr(MEM_ADDR);
}


void Byte_WtNO(uint32 rom_addr,uint8 rom_data)
{
	//u32 Addr = UserStartAddress + rom_addr;
	//if(FLASH_PageErase(rom_addr,1) == FALSE)return;
	FLASH_WrByteDataProgram(rom_addr,rom_data);
}

















//============================================================================================================


void UserflashTest(void)
{
	u16 i;

	MemoryMode=1;
	EEPROMin=16;
	UserA = 1;

	Writebuf[0] = 0;//0x12345678;
	Writebuf[1] = 0;//0x9ABCDEFE;
	Writebuf[2] = 1;//0x12345678;
	Writebuf[3] = 1;//0x9ABCDEFE;

	for(i=0; i< 8; i++)
	{
		outbyte[i] = i+4;
	}

	//FLASH_Unlock();
	//FLASH_PageErase(UserStartAddress,1);
	EEPROMin =0;
	UserA = 1;
	MemoryMode =0;
	writeM24L16();

	readM24L16();

	FLASH_Read(UserStartAddress,RevData,128);//512
	/*for(i=0; i< 512/4; i++)
	{
		SendData[i] = i;
	}
	*/

//	FLASH_PageErase(UserStartAddress,1);

	//FLASH_WrDataProgram(UserStartAddress,SendData,16);

	//FLASH_WrDataProgram(UserStartAddress+16,SendData,16);

	//FLASH_WrDataProgram(UserStartAddress+16*2,SendData,16);

	//FLASH_Read(UserStartAddress,RevData,128);

	//while (1);

}


void ReadUserAllMem(void)
{
	FLASH_Read(UserStartAddress,MemBack,2048/4);

}

u8  CheckUserMemData(void)
{
	unsigned char j;
	u16 Idextemp;
	unsigned char flag;
	outbyte[7]=0;
	FLASH_Read(UserStartAddress,MemBack,2048);
	for(j=0;j<8;j+=4)
	{
			inbyte[j] = (u8)(MemBack[j/4]>>24);
			inbyte[j+1] = (u8)(MemBack[j/4]>>16);
			inbyte[j+2] = (u8)(MemBack[j/4]>>8);
			inbyte[j+3] = (u8)(MemBack[j/4]);
	}

	for(j=0;j<7;j++)
	{
		outbyte[7]+=inbyte[j];//校验
	}
	if(outbyte[7]==inbyte[7])
	{
				//ReadEepromError=0;
				outbyte[7]=0;
				Idextemp = (inbyte[0]-1)*2;//4
				for(j=0;j<8;j+=4)
				{

					inbyte[j] = (u8)(MemBack[(j/4+Idextemp)]>>24);
					inbyte[j+1] = (u8)(MemBack[(j/4+Idextemp)]>>16);
					inbyte[j+2] = (u8)(MemBack[(j/4+Idextemp)]>>8);
					inbyte[j+3] = (u8)(MemBack[(j/4+Idextemp)]);
				}
				for(j=0;j<7;j++)
				{
					outbyte[7]+=inbyte[j];//校验
				}
				if(outbyte[7]==inbyte[7])
				{
					if(((inbyte[0] == 0)&&(inbyte[1] == 0))||((inbyte[0] == 0xFF)&&(inbyte[1] == 0xFF)))flag=1;
					else
					flag=0;
				}
			  else  flag=1;
	}
	else
	{
		flag=1;
	}
	return  flag;
}


u8  CheckUserBackMemData(void)
{
	unsigned char j;
	u16 Idextemp;
	unsigned char flag;
	outbyte[7]=0;
	FLASH_Read(BackStartAddress,MemBack,2048);
	for(j=0;j<8;j+=4)
	{
			inbyte[j] = (u8)(MemBack[j/4]>>24);
			inbyte[j+1] = (u8)(MemBack[j/4]>>16);
			inbyte[j+2] = (u8)(MemBack[j/4]>>8);
			inbyte[j+3] = (u8)(MemBack[j/4]);
	}

	for(j=0;j<7;j++)
	{
			outbyte[7]+=inbyte[j];//校验
	}
	if(outbyte[7]==inbyte[7])
	{
				//ReadEepromError=0;
				outbyte[7]=0;
				Idextemp = (inbyte[0]-1)*2;
				for(j=0;j<8;j+=4)
				{

					inbyte[j] = (u8)(MemBack[(j/4+Idextemp)]>>24);
					inbyte[j+1] = (u8)(MemBack[(j/4+Idextemp)]>>16);
					inbyte[j+2] = (u8)(MemBack[(j/4+Idextemp)]>>8);
					inbyte[j+3] = (u8)(MemBack[(j/4+Idextemp)]);
				}
				for(j=0;j<7;j++)
				{
					outbyte[7]+=inbyte[j];//校验
				}
				if(outbyte[7]==inbyte[7])
				{
					if(((inbyte[0] == 0)&&(inbyte[1] == 0))||((inbyte[0] == 0xFF)&&(inbyte[1] == 0xFF)))flag=1;
					else
					flag=0;
				}
			  else  flag=1;
	}
	else
	{
		flag=1;
	}
	return  flag;
}


void CheckMemDataIsOK(void)
{
	unsigned char flag[2];
	flag[0] = CheckUserMemData();
	flag[1] = CheckUserBackMemData();
	if(flag[0]&&flag[1])
	{
		 CLRMemoryBank();
	}
	else if(flag[0])
	{
		FLASH_Read(BackStartAddress,MemBack,2048);
		FLASH_PageErase(UserStartAddress,4);//512*4
		FLASH_WrDataProgram(UserStartAddress,MemBack,2048);
	}
	else if(flag[1])
	{
		FLASH_Read(UserStartAddress,MemBack,2048);
		FLASH_PageErase(BackStartAddress,4);//512*4
		FLASH_WrDataProgram(BackStartAddress,MemBack,2048);
	}

}


//==================================================================================================


//读8字节
void readM24L16addr(uint32 addr)
{
	unsigned char j;
	unsigned int temp;
	outbyte[7]=0;
	temp=EEPROMin;
	if(!UserA&&MemoryMode) temp+=UserBOffSet;//0x100

	if(temp>256*2)//
	{
		for(j=0;j<8;j++)
		{
			inbyte[j]=0xff;
		}
		ReadEepromError=1;
		return;
	}

	temp*=8;
	FLASH_Read(addr + temp,Readbuf,8);
	for(j=0;j<8;j+=4)
	{
//			inbyte[j]=Byte_RD(temp+j);//读进
			inbyte[j] = (u8)(Readbuf[j/4]>>24);
			inbyte[j+1] = (u8)(Readbuf[j/4]>>16);
			inbyte[j+2] = (u8)(Readbuf[j/4]>>8);
			inbyte[j+3] = (u8)(Readbuf[j/4]);
	}

	for(j=0;j<7;j++)
	{
			outbyte[7]+=inbyte[j];//校验
	}
	if(outbyte[7]==inbyte[7])
		{ReadEepromError=0;}
	else
		{ReadEepromError=1;}

}

//写8字节
void writeM24L16addr(uint32 addr)
{
     unsigned char j;
	    unsigned int temp;

	    temp=EEPROMin;
	    if(!UserA&&MemoryMode) temp+=UserBOffSet;

	    if(temp>256*2) return;//最大组数

	    temp*=8;
	    outbyte[7]=outbyte[0]+outbyte[1]+outbyte[2]+outbyte[3]+outbyte[4]+outbyte[5]+outbyte[6];//+outbyte[7]+outbyte[8]+outbyte[9]+outbyte[10]+outbyte[11]+outbyte[12]+outbyte[13]+outbyte[14];
	    for(j=0;j<8;j+=4)
			{
				//Byte_Wt(temp+j,outbyte[j]);
				Writebuf[j/4] = (u32)(outbyte[j]<<24 | outbyte[j+1]<<16 | outbyte[j+2]<<8 | outbyte[j+3]);

			}
			//FLASH_WrDataProgram(UserStartAddress + temp,Writebuf,16);
			FLASH_Read(addr,MemBack,1024);
			for(j=0;j<2;j++)//8byte
			{
				MemBack[temp/4 + j] = Writebuf[j];//32bit
			}
			FLASH_PageErase(addr,2);//512*2
			FLASH_WrDataProgram(addr,MemBack,1024);

			//FLASH_PageErase(addr,2);//512*2					//back memdata
			//FLASH_WrDataProgram(BackStartAddress,MemBack,2048);

}



//==================================================================================================

//读8字节
void	readM24L16(void)
{
	unsigned char j;
	//unsigned int temp;
	uint16 temp;
	outbyte[7]=0;
	temp=EEPROMin;
	if(!UserA&&MemoryMode) temp+=UserBOffSet;//0x100

	if(temp>256*2)//
	{
		for(j=0;j<8;j++)
		{
			inbyte[j]=0xff;
		}
		ReadEepromError=1;
		return;
	}

	temp*=8;
	FLASH_Read(UserStartAddress + temp,Readbuf,8);
	for(j=0;j<8;j+=4)
	{
//			inbyte[j]=Byte_RD(temp+j);//读进
			inbyte[j] = (u8)(Readbuf[j/4]>>24);
			inbyte[j+1] = (u8)(Readbuf[j/4]>>16);
			inbyte[j+2] = (u8)(Readbuf[j/4]>>8);
			inbyte[j+3] = (u8)(Readbuf[j/4]);
	}

	for(j=0;j<7;j++)
	{
			outbyte[7]+=inbyte[j];//校验
	}
	if(outbyte[7]==inbyte[7])
		{ReadEepromError=0;}
	else
		{ReadEepromError=1;}

}

//写8字节
void writeM24L16(void)
{
      unsigned char j;
	  //  unsigned int temp;
		uint16 temp;

	    temp=EEPROMin;
	    if(!UserA&&MemoryMode) temp+=UserBOffSet;

	    if(temp>256*2) return;//最大组数
		//if(temp>20*1024) return;

	    temp*=8;
	    outbyte[7]=outbyte[0]+outbyte[1]+outbyte[2]+outbyte[3]+outbyte[4]+outbyte[5]+outbyte[6];//+outbyte[7]+outbyte[8]+outbyte[9]+outbyte[10]+outbyte[11]+outbyte[12]+outbyte[13]+outbyte[14];
	    for(j=0;j<8;j+=4)
			{
				//Byte_Wt(temp+j,outbyte[j]);
				Writebuf[j/4] = (u32)(outbyte[j]<<24 | outbyte[j+1]<<16 | outbyte[j+2]<<8 | outbyte[j+3]);

			}
			//FLASH_WrDataProgram(UserStartAddress + temp,Writebuf,16);
			FLASH_Read(UserStartAddress,MemBack,2048);
			for(j=0;j<2;j++)//8byte
			{
				MemBack[temp/4 + j] = Writebuf[j];//32bit
			}
			FLASH_PageErase(UserStartAddress,4);//512*4
			FLASH_WrDataProgram(UserStartAddress,MemBack,2048);

			FLASH_PageErase(BackStartAddress,4);//512*4					//back memdata
			FLASH_WrDataProgram(BackStartAddress,MemBack,2048);

}




//擦除两次
void   CLRMemoryBank(void)//设定Memory初始值
{
	MemoryMode=1;
	EEPROMin=0;
	readM24L16();//分AB user

	outbyte[0]=1;
	outbyte[1]=MemorySet;
	outbyte[2]=inbyte[2];
	outbyte[3]=inbyte[3];
	outbyte[4]=inbyte[4];
	outbyte[5]=inbyte[5];
	outbyte[6]=0;		//MemoryFull

	//FLASH_PageErase(UserStartAddress,4);//512*4  先擦除再写引导区复位值
	EEPROMin=0;
	writeM24L16();//改为写缓存
	//FLASH_Read(UserStartAddress,MemBack,2048);//JACK  TEST 20210603
	MemoryEndIndex = 1;
	MemoryFull = 0;
	MemoryMode=0;

}




//确认存储区是否异常
void   checkmemorybank(void)
{
	MemoryMode=1;
	EEPROMin=0;
	readM24L16();  //检验数据

	if (inbyte[6]==1)
	{
		MemoryFull = 1;
	}
	else
	{
		MemoryFull = 0;
	}
	MemoryEndIndex = inbyte[0];

	if((MemoryEndIndex==0) || (inbyte[6]>1) || ReadEepromError || (MemoryEndIndex>(inbyte[1]+1)))
	{
		CLRMemoryBank();//重新设定索引区的值
	}
	MemoryMode=0;
}


//确认AB用户存储区
void   checkmemorybankAB(void)
{
	MemoryMode=1;
	EEPROMin=0;
	readM24L16();
	if (inbyte[6]==1)
	{
		MemoryFull = 1;
	}
	else
	{
		MemoryFull = 0;
	}
	MemoryEndIndex = inbyte[0];
	MemoryMode=0;
}

//================================================================================================
void savefunction(void)	//手动设定保存功能
{
	u8 i;
	//uint32 OutTemp[2];
	outbyte[0]=BPLevelType<<4;
	outbyte[0]|=UartType;
 	outbyte[1]=KeyNumber<<4;
	outbyte[1]|=VoiceType;
	outbyte[2]=MemorySetType<<4;
	outbyte[2]|=VoiceType2;
	outbyte[3]=SystemSetFlag4.b;
	outbyte[4]=SystemSetFlag.b;
	outbyte[5]=SystemSetFlag2.b;
	outbyte[6]=SystemSetFlag3.b;
	outbyte[7]=outbyte[0]+outbyte[1]+outbyte[2]+outbyte[3]+outbyte[4]+outbyte[5]+outbyte[6];
	//OutTemp[0] = outbyte[0]<<24 | outbyte[1]<<16 | outbyte[2]<<8 | outbyte[3];
	//OutTemp[1] = outbyte[4]<<24 | outbyte[5]<<16 | outbyte[6]<<8 | outbyte[7];
	//FLASH_WrDataProgram(FunctionAdd,OutTemp,8);
	//FLASH_WrDataProgram(FunctionBak,OutTemp,8);
	FLASH_PageErase(FunctionAdd,1);
	for(i=0;i<8;i++)
	{
		Byte_WtNO(FunctionAdd+i,outbyte[i]);
		Byte_WtNO(FunctionBak+i,outbyte[i]);
	}

}


volatile uint8 who_threshold_sum;  //who等级播报的数量

const uint8 *p_sys_who_threshold;  //who等级阈值指针
const uint8 *p_dia_who_threshold;  //who等级阈值指针
//阈值表 [0][X]是收缩压 \[1][X]是舒张压
const uint8 sys_who_threshold_table_1[5] = {120,130,140,160,180}; //WYK && urion \标准who 常用
const uint8 dia_who_threshold_table_1[5] = {80,85,90,100,110};


const uint8 sys_who_threshold_table_2[6] = {90,120,130,140,160,180}; //axd
const uint8 dia_who_threshold_table_2[6] = {60,80,85,90,100,110};

#define    SYS_HRESHOLD(a)  p_sys_who_threshold[a]//收缩压阈值 取地址
#define    DIA_THRESHOLD(a)  p_dia_who_threshold[a]//舒张压阈值


typedef enum e_write_stat
{
    WRITE_OTHER = 0, //写其它 即除了平均血压和阈值的其它记忆
    WRITE_1_TO_3 = 1, //写1到3组平均记忆
    WRITE_4_TO_6 = 2, //写4到6组记忆 最小一组阈值
    WRITE_7_TO_THRESHOLD_END = 3, //写7组以上  即阈值1以上到结束的记忆
    WRITE_END = 4, //写记忆结束
}e_write_stat_typedef;

typedef enum e_threshold
{
    E_HRESHOLD_URION = 0,
    E_HRESHOLD_WYK_103 = 1,
    E_HRESHOLD_AXD = 2,
}e_hreshold_typedef;
//可定义选择的功能以及初值 // ----------------------------------------------------------------
e_hreshold_typedef e_threshold = E_HRESHOLD_URION; //选择阈值组
#define WRITE_MEM_YEAR_INIT  23 //写入的开始时间的初值定义
#define WRITE_MEM_MONTH_INIT 5
#define WRITE_MEM_DAY_INIT 11
//写第4-6组记忆时 写入特殊标志位\心率高低
#define IS_WRITE_ARRHYTHMIA_FLAG  1 //写心律不齐选择  \1:写心律不齐 标志位 \0:不写心律不齐 标志位
#define IS_WRITE_CUFF_FLAG  1//写绑带松紧选择 \1:写绑带松紧 标志位 \0:不写绑带松紧 标志位
#define IS_WRITE_MOVE_FLAG  1// 写误动作选择 \1:写误动作 标志位 \0:不写误动作 标志位
#define PULSE_HIGH  222 //要写入的心率高值 Hi 应用于第4-6组的写特殊记忆
#define PULSE_LOW  33//要写入的心率低值 Lo
#define IS_DISPLAY_NEW_VERSION_WRITE_FULL_MEM 1 //写满记忆显示方式选择 \1: 使用新版本的显示方式 \0: 使用旧版本的显示方式

void switch_sys_dia_hreshold(e_hreshold_typedef e_threshold)
{
    switch (e_threshold)
    {
    case E_HRESHOLD_AXD :
        who_threshold_sum = sizeof(sys_who_threshold_table_2);
        // who_threshold_sum = 6;
        p_sys_who_threshold = &sys_who_threshold_table_2[0];
        p_dia_who_threshold = &dia_who_threshold_table_2[0];
        break;
    case E_HRESHOLD_WYK_103:
    case E_HRESHOLD_URION:
        // who_threshold_sum = 5;
        who_threshold_sum = sizeof(sys_who_threshold_table_1);
        p_sys_who_threshold = &sys_who_threshold_table_1[0];
        p_dia_who_threshold = &dia_who_threshold_table_1[0];
        break;

    default:
        break;
    }
}

void disply_write_full_mem(uint8 sys, uint8 dia,uint8 pul)
{
    DisplayToSYSDIA(sys, 1);  //
    DisplayToSYSDIA(dia, 2);  //
    DisplayToPUL(pul); //
}


void writeFULLmemorybank(void)
{
//    uint8 i= 0;
    // uint8 who_num_count = 0;
    uint8 who_num_idex = 0;
    // uint8 who_num_idex_2 = 0;
    uint8 who_buff_idex = 0;
    uint8 temp = 0;
    uint16 write_count = 0;
    e_write_stat_typedef e_write_stat = WRITE_OTHER;
    uint8 year_temp = 0; //特殊处理 将时间还原
    uint8 month_temp = 0;
    uint8 day_temp = 0;
    uint8 hour_temp = 0;
    uint8 min_temp = 0;
    uint8 write_other_stat = 0;

    year_temp = Year.b;
    month_temp = Month;
    day_temp = Day;
    hour_temp = Hour;
    min_temp = Minute;

    switch_sys_dia_hreshold(e_threshold);
    MemoryMode = 1;
    Minute = 0; /*  Minute Value */
    Hour = 12;  /*  Hour Value */
    Day = WRITE_MEM_DAY_INIT;    /*  Day Value */
    Month = WRITE_MEM_MONTH_INIT;  /*  Month Value */
    Year.b = WRITE_MEM_YEAR_INIT;
    delay(8);
    CLRMemoryBank();
    write_count = 1;
    while (1)
    {
        MemoryMode = 1;
        Hour = write_count % 24;
        Minute = write_count % 60;
        ResultDataDA = Day + (Month & 0x03) * 64; // M0+data
        ResultDataHO = Hour + (Month & 0x0c) * 16;
        ResultDataMI = Minute;
        Day += 5;
        if (Day > 25)
        {
            Day = 1;
            Month++;
            if (Month == 13)
            {
                Month = 1;
                Year.b++;
            }
        }

        switch (e_write_stat)
        {
        case WRITE_OTHER:
            if (write_count >= MemorySet - ((who_threshold_sum * 3) + 3))
            {
                e_write_stat = WRITE_7_TO_THRESHOLD_END;
                who_buff_idex = who_threshold_sum - 1;
                who_num_idex = 2;
            }
            if (write_other_stat == 0)
            {
                ResultDataS = SYS_HRESHOLD(0) + ((MemorySet - ((who_threshold_sum * 3) + 3))- write_count);
                ResultDataD = DIA_THRESHOLD(0) + ((MemorySet - ((who_threshold_sum * 3) + 3)) - write_count);
                if (ResultDataS < ResultDataD)
                {
                    ResultDataS = ResultDataD;
                    write_other_stat = 1;
                }
            }
            else
            {
                ResultDataS = SYS_HRESHOLD(0) + write_count;
                ResultDataD = DIA_THRESHOLD(0) + write_count;
                if (ResultDataS < ResultDataD)
                {
                    ResultDataS = ResultDataD;
                    write_other_stat = 0;
                }
            }
            ResultDataH = 40 + write_count;
            break;

        case WRITE_7_TO_THRESHOLD_END:
            if (write_count >= MemorySet - 6)
            {
                who_num_idex = 2;
                e_write_stat = WRITE_4_TO_6;
            }


            if (who_num_idex == 0) //阈值的最后一组
            {
                ResultDataS = SYS_HRESHOLD(who_buff_idex);
                ResultDataD = DIA_THRESHOLD(who_buff_idex);
                ResultDataH = 77;
            }
            else if (who_num_idex == 1)//阈值的中间的一组
            {
                ResultDataS = SYS_HRESHOLD(who_buff_idex) - 1;
                ResultDataD = DIA_THRESHOLD(who_buff_idex) - 1;
                ResultDataH = 66;
            }
            else if (who_num_idex == 2)//阈值开始的一组
            {
                temp = (SYS_HRESHOLD(who_buff_idex) - SYS_HRESHOLD(who_buff_idex - 1)) /2; //取相邻两组中位值
                ResultDataS = SYS_HRESHOLD(who_buff_idex) - temp;
                temp = (DIA_THRESHOLD(who_buff_idex) - DIA_THRESHOLD(who_buff_idex - 1)) /2;
                ResultDataD = DIA_THRESHOLD(who_buff_idex) - temp;
                ResultDataH = 55;
                who_buff_idex--;
            }
            break;
        case WRITE_4_TO_6:

            if (write_count >= MemorySet - 3)
            {
                who_num_idex = 2;
                e_write_stat = WRITE_1_TO_3;
            }

            #if (IS_WRITE_ARRHYTHMIA_FLAG == 1)
            ResultDataMI |= 0x80; // 20110306增加如果本笔记忆有PAD则写入Memory.
            #endif

            #if (IS_WRITE_CUFF_FLAG == 1)
                ResultDataHO|=0x20;
            #endif

            #if (IS_WRITE_MOVE_FLAG == 1)
            ResultDataDA|=0x20;  //Byte3 bit5
            #endif

            if (who_num_idex == 0) //阈值的最后一组
            {
                ResultDataS = SYS_HRESHOLD(0);
                ResultDataD = DIA_THRESHOLD(0);
                ResultDataH = PULSE_HIGH;
            }
            else if (who_num_idex == 1)//阈值的中间的一组
            {
                ResultDataS = SYS_HRESHOLD(0) - 1;
                ResultDataD = DIA_THRESHOLD(0) - 1;
                ResultDataH = 66;
            }
            else if (who_num_idex == 2)//阈值开始的一组
            {
                ResultDataS = SYS_HRESHOLD(0) - 20;
                ResultDataD = DIA_THRESHOLD(0) - 15;
                ResultDataH = PULSE_LOW;
            }
            break;

        case WRITE_1_TO_3:
            if (write_count >= MemorySet)
            {
                e_write_stat = WRITE_END;
            }


            if (who_num_idex == 0) //阈值的最后一组
            {
                ResultDataS = 122;
                ResultDataD = 82;
                ResultDataH = 62;
            }
            else if (who_num_idex == 1)//阈值的中间的一组
            {
                ResultDataS = 121;
                ResultDataD = 81;
                ResultDataH = 61;
            }
            else if (who_num_idex == 2)//阈值开始的一组
            {
                ResultDataS = 120;
                ResultDataD = 80;
                ResultDataH = 60;
            }
            break;

        case WRITE_END:
            goto WRITE_OVER;
            break;

        default:
            break;
        }
        savetomemory();
#if (IS_DISPLAY_NEW_VERSION_WRITE_FULL_MEM == 1)
        DarkAllIcon();
        disply_write_full_mem(ResultDataS, ResultDataD, ResultDataH);
        DisplayToMemorySet(MemoryEndIndex);
        showtime();
        MonthIconOn;
        TimePointIconOn;
        showdate();
        ShowWHO(ResultDataS,ResultDataD);
        UserABDisplay();
        // HeartIconOn;
        MemoryIconOn;
        delay(2);
#else
		DisplayToSYSDIA(write_count,2);
		DisplayToPUL(MemoryEndIndex);
#endif
        // DisplayToSYSDIA(Det_DIA, 2);
        // DisplayToPUL(MemoryEndIndex);
        write_count++;
        who_num_idex++;
        if (who_num_idex > 2)
        {
            who_num_idex = 0;
        }

    }

WRITE_OVER:
    MemoryMode = 1;
    EEPROMin = 0;
    readM24L16();

    outbyte[0] = MemoryEndIndex;
    outbyte[1] = MemorySet;
    outbyte[2] = inbyte[2];
    outbyte[3] = inbyte[3];
    outbyte[4] = inbyte[4];
    outbyte[5] = inbyte[5];
    if (MemoryFull)
        outbyte[6] = 1;
    else
        outbyte[6] = 0;

    EEPROMin = 0;
    writeM24L16();

    MemoryMode = 0;
    Year.b = year_temp; //特殊处理 将时间还原
    Month = month_temp;
    Day = day_temp;
    Hour = hour_temp;
    Minute = min_temp;
}


void   old_writeFULLmemorybank(void)
{
	MemoryMode=1;
	Minute=0;		/*  Minute Value */
	Hour=12;                /*  Hour Value */
	Day=1;                 	/*  Day Value */
	Month=1;               	/*  Month Value */
 	Year.b=6;
	delay(8);
 	CLRMemoryBank();
	Det_DIA=1;
	do
	{
	    MemoryMode=1;
	    if(Det_DIA<4)
	    	{
	    		if(Det_DIA==1)
	    			{
	    				ResultDataS = 180;
						ResultDataD = 100;
						ResultDataH = 80;
					}
				if(Det_DIA==2)
	    			{
	    				ResultDataS = 130;
						ResultDataD = 55;
						ResultDataH = 80;
					}
				if(Det_DIA==3)
	    			{
	    				ResultDataS = 120;
						ResultDataD = 80;
						ResultDataH = 80;
					}
				if(Det_DIA==4)
	    			{
	    				ResultDataS = 110;
						ResultDataD = 70;
						ResultDataH = 80;
					}
			}
		else
			{
				ResultDataS = 200-Det_DIA;
				ResultDataD = 140-Det_DIA;
				ResultDataH = 40+Det_DIA;
			}
		Day+=5;
		if (Day>25)
			{
	        	 Day=1;
	        	 Month++;
	        	 if (Month==13)
	        	 {
	        	 	 Month=1;
	        	 	 Year.b++;
	        	 }
	        }

		Hour=Det_DIA%24;
		Minute=Det_DIA%60;
		ResultDataDA = Day+(Month&0x03)*64;		//M0+data
		ResultDataHO = Hour+(Month&0x0c)*16;
		ResultDataMI = Minute;

//		lastmodeAV ^= 1;				//set average mode
		savetomemory();
		DisplayToSYSDIA(Det_DIA,2);
		DisplayToPUL(MemoryEndIndex);
		Det_DIA++;
        delay(1);//连续存储可能引起写flash卡死，增加延迟  202306
	}while(Det_DIA<=IDbuffer.b);


	MemoryMode=1;
  	EEPROMin=0;
    readM24L16();

   	outbyte[0]=MemoryEndIndex;
	outbyte[1]=MemorySet;
	outbyte[2]=inbyte[2];
	outbyte[3]=inbyte[3];
	outbyte[4]=inbyte[4];
	outbyte[5]=inbyte[5];
	if (MemoryFull)	outbyte[6]=1;
	else outbyte[6]=0;

	EEPROMin=0;
	writeM24L16();

	MemoryMode=0;
}



void SaveSet(void)	//保存用户设定
{
		uint8 i;
		for(i=0;i<3;i++)
		{
				//EEPROMin = UserSetAdd+i;
				//readM24L16();//JACK
				EEPROMin = i;
				readM24L16addr(UserSetAdd);
				if(mmHgkPaFlag==1){outbyte[0]=inbyte[0]|0x01;}
				else{outbyte[0]=inbyte[0]&0xfe;}

				if(VoiceEnable==1){outbyte[0]=outbyte[0]|0x02;}
				else{outbyte[0]=outbyte[0]&0xfd;}

				if(UserA==1){outbyte[0]=outbyte[0]|0x04;}
				else{outbyte[0]=outbyte[0]&0xfb;}
				outbyte[1]=VoiceLevel;
				outbyte[2]=inbyte[2];
				outbyte[3]=inbyte[3];
				outbyte[4]=inbyte[4];
				outbyte[5]=inbyte[5];
				outbyte[6]=inbyte[6];
				//writeM24L16();
				writeM24L16addr(UserSetAdd);
		}
}

void checkeeprom(void)
{	MemoryMode=1;
	checkmemorybankAB();
	DarkAllIcon();
	if(MemoryFull)						//Memory full
		{
			DisplayToMemorySet(MemorySet);
 		}
 	else								//Memory not full
     	{
  			DisplayToMemorySet(MemoryEndIndex-1);
      	}
	UserABDisplay();
	ShowVoice();
    delay(64);
	MemoryMode=0;
}

void LoadMemory(void)
{
	MemoryMode=1;
	checkmemorybankAB();
	MemoryMode=1;
	EEPROMin = 0;
	readM24L16();

	MemoryEndIndex = inbyte[0]-1;

	if(MemoryFull)	{MemoryIndex = MemorySet;}
	else			{MemoryIndex = MemoryEndIndex;}

	if((MemoryEndIndex==0 && MemoryFull==0)||(ReadEepromError==1)||(MemoryEndIndex>MemorySet)) MemoryIndex=0;

	DisplayToMemorySet(MemoryIndex);
}


void CheckEepromIsOk(void)
{

}






//======================test flash=================================


void FlashWrByteNOTest(uint32 rom_addr)	//手动设定保存功能
{
	u8 i;
	for(i=0;i<7;i++)
	{
		outbyte[i] = i;
	}

	outbyte[7]=outbyte[0]+outbyte[1]+outbyte[2]+outbyte[3]+outbyte[4]+outbyte[5]+outbyte[6];
	FLASH_PageErase(rom_addr,1);
	for(i=0;i<8;i++)
	{
		Byte_WtNO(rom_addr+i,outbyte[i]);
	}

}


void FlashRdByteNOTest(uint32 rom_addr)
{

	uint8 i;
	for(i=0;i<8;i++)
	{
		inbyte[i]=0;
	}
	for(i=0;i<8;i++)
	{
		inbyte[i]=Byte_RDNO(rom_addr+i);
	}
}





void MemTset(void)
{
	uint8  k,m;
	/*FlashWrByteNOTest(FunctionAdd);
	delay(10);
	FlashRdByteNOTest(FunctionAdd);
	delay(10);

	FlashWrByteNOTest(FunctionBak);
	delay(10);
	FlashRdByteNOTest(FunctionBak);
	delay(10);


	FlashWrByteNOTest(EEPROMCheckAdd);
	delay(10);
	FlashRdByteNOTest(EEPROMCheckAdd);
	delay(10);

	FlashWrByteNOTest(CalBak);
	delay(10);
	FlashRdByteNOTest(CalBak);
	delay(10);

	FlashWrByteNOTest(CalAdd);
	delay(10);
	FlashRdByteNOTest(CalAdd);*/
	delay(10);
	UserA= 0;
	MemoryMode =1;//user2
	for(m=0;m<100;m++)
	{
		EEPROMin =m;
		for(k=0;k<8;k++)
		{
			outbyte[k]  = 0;
		}

		for(k=0;k<7;k++)
		{
			outbyte[k]  = k;
			//outbyte[7]  +=outbyte[k];
		}
		writeM24L16();
		delay(10);

		for(k=0;k<8;k++)
		{
			inbyte[k]  = 0;
		}
		readM24L16();
		delay(10);
	}


#if 0

	ResultDataS = SystolicValue1b = 120;
	ResultDataD = DiastolicValue = 80;
	ResultDataH = PulseRate =60;
	resultdata();

	checkmemorybankAB();
	MemoryMode=1;
	EEPROMin = 0;
	readM24L16();
#endif

}

